/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package firmasotro;

import java.util.*;
import java.io.*;
import java.security.*;
import javax.crypto.*;
import java.security.spec.*;
import javax.crypto.spec.*;

public class FirmaArchivo implements Constantes {

    public static void main(String[] args) throws Exception {
// Pedimos el fichero a firmar
// y fichero de clave privada a usar
     Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

        BufferedReader teclado = new BufferedReader(
                new InputStreamReader(System.in));
        System.out.print("Indique fichero a firmar:");
        String fichero_firmar = teclado.readLine();
        if (!new File(fichero_firmar).exists()) {
            System.out.println("El fichero "
                    + fichero_firmar + " no existe");
            return;
        }
        String fichero_firma = fichero_firmar + ".sign";
// Recuperamos la clave privada
        System.out.print("Indique que fichero tiene la"
                + " clave privada a usar:");
        String fichero_privada = teclado.readLine();
        System.out.print(
                "Indique password con que se encripto el fichero "
                + fichero_privada + ":");
        String password = teclado.readLine();
        System.out.println(
                "Recuperando clave privada...");
        SecureRandom sr = new SecureRandom();
        sr.setSeed(new Date().getTime());
        FileInputStream fis =
                new FileInputStream(fichero_privada);
        byte[] buffer = new byte[TAMANO_SALT_BYTES];
        fis.read(buffer);
        PBEKeySpec clave_pbe_spec =
                new PBEKeySpec(password.toCharArray());
        SecretKey clave_pbe =
                SecretKeyFactory.getInstance(
                "PBEWithSHAAndTwofish-CBC").generateSecret(
                clave_pbe_spec);
        PBEParameterSpec param_pbe_spec =
                new PBEParameterSpec(buffer, ITERACIONES_PBE);
        Cipher descifrador_pbe = Cipher.getInstance(
                "PBEWithSHAAndTwofish-CBC");
        descifrador_pbe.init(Cipher.DECRYPT_MODE,
                clave_pbe, param_pbe_spec, sr);
        buffer = new byte[fis.available()];
        fis.read(buffer);
        fis.close();
        buffer = descifrador_pbe.doFinal(buffer);
        PKCS8EncodedKeySpec clave_privada_spec =
                new PKCS8EncodedKeySpec(buffer);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        PrivateKey clave_privada =
                kf.generatePrivate(clave_privada_spec);
        System.out.println("Clave secreta recuperada");
// Firmamos el fichero
        fis = new FileInputStream(fichero_firmar);
        Signature s = Signature.getInstance("SHA1withRSA");
        s.initSign(clave_privada);
        buffer = new byte[1024];
        while (fis.available() >= 1024) {
            fis.read(buffer);
            s.update(buffer);
        }
        int quedan = fis.available();
        fis.read(buffer, 0, quedan);
        s.update(buffer, 0, quedan);
        buffer = s.sign();
        fis.close();
        FileOutputStream fos =
                new FileOutputStream(fichero_firma);
        fos.write(buffer);
        fos.close();
        System.out.println(
                "Fichero firmado, la firma se deposito en "
                + fichero_firma);
    }
}
